﻿' ----------------------------------------------------------------------------------
' Microsoft Developer & Platform Evangelism
' 
' Copyright (c) Microsoft Corporation. All rights reserved.
' 
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
' OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ----------------------------------------------------------------------------------
' The example companies, organizations, products, domain names,
' e-mail addresses, logos, people, places, and events depicted
' herein are fictitious.  No association with any real company,
' organization, product, domain name, email address, logo, person,
' places, or events is intended or should be inferred.
' ----------------------------------------------------------------------------------

Imports Microsoft.Samples.WindowsPhoneCloud.StorageClient
Imports System.Windows.Threading
Imports System.Globalization
Imports System.Data.Services.Client

Namespace ViewModel

    Public MustInherit Class TableBaseViewModel(Of T)
        Inherits PivotItemViewModel
        Private messageValue As String
        Private isLoadingValue As Boolean = False

        <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification:="The TableName property specifies the 'context name' from where to resolve the class dependencies.")>
        Public Sub New(ByVal cloudClientFactory As ICloudClientFactory, ByVal dispatcher As Dispatcher)
            cloudClientFactory.CleanTablesClientsKey(Me.TableName)

            Me.Context = cloudClientFactory.ResolveTablesServiceContext(Me.TableName)
            Me.Table = cloudClientFactory.ResolveDataServiceCollection(Of T)(Me.TableName)

            AddHandler Me.Table.LoadCompleted, AddressOf Me.OnTableLoaded
            Me.Dispatcher = dispatcher
        End Sub

        Public Property Table() As DataServiceCollection(Of T)

        Public Property Message() As String
            Get
                Return Me.messageValue
            End Get

            Set(ByVal value As String)
                If Me.messageValue <> value Then
                    Me.messageValue = value
                    Me.NotifyPropertyChanged("Message")
                End If
            End Set
        End Property

        Public Property IsLoading() As Boolean
            Get
                Return Me.isLoadingValue
            End Get

            Set(ByVal value As Boolean)
                If Me.isLoadingValue <> value Then
                    Me.isLoadingValue = value
                    Me.NotifyPropertyChanged("IsLoading")
                End If
            End Set
        End Property

        Public MustOverride ReadOnly Property TableName() As String

        Public Property Context() As ITableServiceContext

        Protected Property Dispatcher() As Dispatcher

        Public Overridable Sub LoadTable()
            ' adding an incremental seed to avoid a cached response
            Dim tableUri = New Uri(String.Format(CultureInfo.InvariantCulture, "{0}/{1}?incrementalSeed={2}", Me.Context.BaseUri, Me.TableName, Date.UtcNow.Ticks), UriKind.Absolute)

            Me.IsLoading = True
            Me.Message = "Loading..."

            Me.Table.Clear()
            Try
                Me.Table.LoadAsync(tableUri)
            Catch exception As Exception
                Dim errorMessage = StorageClientExceptionParser.ParseDataServiceException(exception).Message

                Me.IsLoading = False
                Me.Message = String.Format(CultureInfo.InvariantCulture, "Error: {0}", errorMessage)
            End Try
        End Sub

        Protected Overridable Sub OnTableLoaded(ByVal sender As Object, ByVal e As LoadCompletedEventArgs)
            If e.Cancelled Then
                Me.DispatchResult("The operation has been cancelled.")
            ElseIf e.Error IsNot Nothing Then
                Dim errorMessage = StorageClientExceptionParser.ParseDataServiceException(e.Error).Message
                Me.DispatchResult(String.Format(CultureInfo.InvariantCulture, "Error: {0}", errorMessage))
            ElseIf Me.Table.Continuation IsNot Nothing Then
                Me.Table.LoadNextPartialSetAsync()
            Else
                Me.DispatchResult()
            End If
        End Sub

        Protected Overridable Sub DispatchResult(Optional ByVal message As String = "")
            Me.Dispatcher.BeginInvoke(
                Sub()
                    Me.Message = message
                    Me.IsLoading = False
                End Sub)
        End Sub
    End Class
End Namespace